package com.springboot_shopping.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.springboot_shopping.Mapper.OrderItemMapper;
import com.springboot_shopping.Mapper.OrderMapper;
import com.springboot_shopping.Mapper.PictureMapper;
import com.springboot_shopping.Mapper.ProductMapper;
import com.springboot_shopping.entity.Order;
import com.springboot_shopping.entity.OrderItem;
import com.springboot_shopping.entity.Picture;
import com.springboot_shopping.entity.Product;
import com.springboot_shopping.service.OrderService;
import com.springboot_shopping.utils.OrderNoGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderItemMapper orderItemMapper;
    @Autowired
    private PictureMapper pictureMapper;
    @Autowired
    private ProductMapper productMapper;
    @Autowired
    private OrderMapper orderMapper;

    @Override
    @Transactional
    public boolean createOrder(Order order, List<Integer> cartItemIds, Integer addressId) {
        try {
            // 1. 生成订单号（时间戳+随机数）
            order.setOrderNo(OrderNoGenerator.generateOrderNo());

            // 2. 设置订单基本信息
            order.setCreateTime(new Date());
            order.setUpdateTime(new Date());
            order.setStatus(2); // 待付款状态
            order.setTotalPrice(order.getTotalPrice()); // 初始化为0

            // 3. 插入订单主表
//            boolean save = this.save(order);
            orderMapper.insert(order);
            Integer orderId = order.getId();
            List<OrderItem> orderItems = new ArrayList<>();
            for(Integer id:cartItemIds){
                OrderItem  orderItem=new OrderItem();
                orderItem.setPrice(order.getTotalPrice());
                orderItem.setQuantity(1);
                orderItem.setOrderId(orderId);
                orderItem.setCreateTime(new Date());
                orderItem.setUpdateTime(new Date());
                orderItem.setProductId(id);
                orderItems.add(orderItem);
            }
            orderItemMapper.insertBatch(orderItems);
            // 4. 处理订单明细
//            List<OrderItem> orderItems = convertCartItemsToOrderItems(cartItemIds, order.getId());
            // 检查订单明细是否为空
            if (orderItems.isEmpty()) {
                throw new RuntimeException("订单明细不能为空，请检查购物车项");
            }

            // 批量插入订单明细
            orderItemMapper.insertBatch(orderItems);

            // 5. 计算并更新订单总金额
            BigDecimal totalPrice = calculateTotalPrice(orderItems);
            order.setTotalPrice(totalPrice);
            this.updateById(order);

            return true;
        } catch (Exception e) {
            // 记录详细错误日志
            log.error("创建订单失败: {}", e.getMessage());
            e.printStackTrace();
            // 事务会自动回滚
            return false;
        }
    }
    @Override
    public List<Order> findOrdersWithItemsAndProducts(Integer userId) {
        // 1. 查询该用户所有订单
        List<Order> orders = orderMapper.selectList(
                new QueryWrapper<Order>().eq("user_id", userId).orderByDesc("create_time")
        );
        System.out.println(orders);
        if (orders == null || orders.isEmpty()) return Collections.emptyList();
        // 2. 查询所有订单id
        List<Integer> orderIds = orders.stream().map(Order::getId).collect(Collectors.toList());
        // 3. 查询所有订单项
        List<OrderItem> allOrderItems = orderItemMapper.selectList(
                new QueryWrapper<OrderItem>().in("order_id", orderIds)
        );
        System.out.println(allOrderItems);
        List<Integer> productIds = allOrderItems.stream().map(OrderItem::getProductId).collect(Collectors.toList());
        System.out.println(productIds);
        Map<Integer, Product> productMap = new HashMap<>();
        if (!productIds.isEmpty()) {
            List<Product> products = productMapper.selectBatchIds(productIds);
            products.forEach(prod -> productMap.put(prod.getId(), prod));
        }
        Map<Integer, List<OrderItem>> orderItemMap = new HashMap<>();
        for (OrderItem item : allOrderItems) {
            Product prod = productMap.get(item.getProductId());
            if (prod != null) {
                item.setProductTitle(prod.getTitle());
                item.setPrice(BigDecimal.valueOf(Double.valueOf(prod.getPrice())));
            }
            orderItemMap.computeIfAbsent(item.getOrderId(), k -> new ArrayList<>()).add(item);
        }
        for (Order order : orders) {
            order.setOrderItems(orderItemMap.getOrDefault(order.getId(), new ArrayList<>()));
        }
        return orders;
    }
    @Override
    @Transactional
    public boolean deleteOrder(Integer orderId) {
        try {
            // 1. 删除订单明细
            LambdaQueryWrapper<OrderItem> itemWrapper = new LambdaQueryWrapper<>();
            itemWrapper.eq(OrderItem::getOrderId, orderId);
            orderItemMapper.delete(itemWrapper);

            // 2. 删除订单主表
            return this.removeById(orderId);
        } catch (Exception e) {
            log.error("删除订单失败: {}", e.getMessage());
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public List<Order> findByUserId(Integer userId) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getUserId, userId);
        wrapper.orderByDesc(Order::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<Order> findByOrderNoLike(String orderNo, Integer userId) {
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getUserId, userId);
        wrapper.like(Order::getOrderNo, orderNo);
        wrapper.orderByDesc(Order::getCreateTime);
        return this.list(wrapper);
    }

    @Override
    public List<Order> searchOrders(String keyword, Integer userId) {
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("user_id", userId);
        wrapper.and(qw -> qw.like("order_no", keyword)
                .or().like("product_name", keyword));
        wrapper.orderByDesc("create_time");
        return orderMapper.searchOrders("%" + keyword + "%", userId);
    }

    @Override
    public IPage<Order> findByPage(Page<Order> page, Wrapper<Order> wrapper) {
        return this.page(page, wrapper);
    }

    // 辅助方法：购物车项转换为订单明细
    private List<OrderItem> convertCartItemsToOrderItems(List<Integer> cartItemIds, Integer orderId) {
        List<OrderItem> orderItems = new ArrayList<>();

        // 实际开发中需从购物车服务获取真实数据
        // 这里使用模拟数据用于测试
        for (Integer cartItemId : cartItemIds) {
            OrderItem item = new OrderItem();
            item.setOrderId(orderId);

            // 实际应为商品ID，这里简化使用cartItemId作为productId
            item.setProductId(cartItemId);

            // 实际应从购物车获取数量，这里默认设为1
            item.setQuantity(1);

            // 实际应从商品服务获取价格，这里使用固定值100.00
            item.setPrice(new BigDecimal("100.00"));

            // 注意：create_time和update_time由数据库自动生成
            orderItems.add(item);
        }
        return orderItems;
    }

    // 计算订单总金额
    private BigDecimal calculateTotalPrice(List<OrderItem> orderItems) {
        BigDecimal total = BigDecimal.ZERO;
        for (OrderItem item : orderItems) {
            // 价格 × 数量
            BigDecimal itemTotal = item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity()));
            total = total.add(itemTotal);
        }
        return total;
    }

    // 添加日志记录（可选）
    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(OrderServiceImpl.class);
}